package com.google.p.code.springscim.openapi.v1;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.p.code.springscim.exception.ScimException;
import com.google.p.code.springscim.schema.ScimQueryParameter;
import com.google.p.code.springscim.schema.model.ScimGroup;
import com.google.p.code.springscim.schema.model.ScimUser;
import com.google.p.code.springscim.spi.ScimServiceProvider;

/**
 * http://www.simplecloud.info/specs/draft-scim-api-01.html
 */
@Controller
@RequestMapping("/scim/v1")
public class ScimRestService {
    
    @Autowired
    private ScimServiceProvider scimServiceFactory;
    
    // **********************************************************
    // User /Users GET, POST, PUT, PATCH, DELETE Retrieve/Add/Modify Users
    // **********************************************************
    @RequestMapping(value = "/Users/{id}", method = RequestMethod.GET)
    @ResponseBody
    public Object getUsers(@PathVariable String id) {
        return scimServiceFactory.getUserService().findById(id);
    }
    
    @RequestMapping(value = "/Users", method = RequestMethod.GET)
    @ResponseBody
    public Object getUsers(ScimQueryParameter param) {
        return null;
    }
    
    @RequestMapping(value = "/Users", method = RequestMethod.POST)
    @ResponseBody
    public Object addUsers(@RequestBody ScimUser user) {
        scimServiceFactory.getUserService().addUser(user);
        return user;
    }
    
    @RequestMapping(value = "/Users/{id}", method = RequestMethod.PUT)
    @ResponseBody
    public Object modifyUsers(@PathVariable String id,
                              @RequestBody ScimUser user) {
        scimServiceFactory.getUserService().updateUser(id, user);
        return scimServiceFactory.getUserService().findById(id);
    }
    
    @RequestMapping(value = "/Users/{id}", method = RequestMethod.DELETE)
    @ResponseBody
    public Object deleteUsers(@PathVariable String id) {
        scimServiceFactory.getUserService().deleteById(id);
        return null;
    }
    
    // TODO : patch unsupported
    
    // **********************************************************
    // Group /Groups GET, POST, PUT, PATCH, DELETE Retrieve/Add/Modify Groups
    // **********************************************************
    
    @RequestMapping(value = "/Groups/{id}", method = RequestMethod.GET)
    @ResponseBody
    public Object getGroups(@PathVariable String id) {
        return scimServiceFactory.getGroupService().findById(id);
    }
    
    @RequestMapping(value = "/Groups", method = RequestMethod.GET)
    @ResponseBody
    public Object getGroups(ScimQueryParameter param) {
        return null;
    }
    
    @RequestMapping(value = "/Groups", method = RequestMethod.POST)
    @ResponseBody
    public Object addGroups(@RequestBody ScimGroup group) {
        scimServiceFactory.getGroupService().addGroup(group);
        return group;
    }
    
    @RequestMapping(value = "/Groups/{id}", method = RequestMethod.PUT)
    @ResponseBody
    public Object modifyGroups(@PathVariable String id,
                               @RequestBody ScimGroup group) {
        scimServiceFactory.getGroupService().updateGroup(id, group);
        return scimServiceFactory.getGroupService().findById(id);
    }
    
    @RequestMapping(value = "/Groups/{id}", method = RequestMethod.DELETE)
    @ResponseBody
    public Object deleteGroups(@PathVariable String id) {
        scimServiceFactory.getGroupService().deleteById(id);
        return null;
    }
    
    // TODO : patch unsupported
    
    // **********************************************************
    // Schema /Schemas GET Retrieve a Resource's Schema
    // **********************************************************
    
    @RequestMapping(value = "/Schemas/Users", method = RequestMethod.GET)
    @ResponseBody
    public Object getSchemasOfUsers() {
        return scimServiceFactory.getSchemaService().getUsersSchema();
    }
    
    @RequestMapping(value = "/Schemas/Groups", method = RequestMethod.GET)
    @ResponseBody
    public Object getSchemasOfGroups() {
        return scimServiceFactory.getSchemaService().getGroupsSchema();
    }
    
    // **********************************************************
    // Service Provider Configuration /ServiceProviderConfigs GET Retrieve the
    // Service Provider's Configuration
    // **********************************************************
    
    @RequestMapping(value = "/ServiceProviderConfigs", method = RequestMethod.GET)
    @ResponseBody
    public Object getServiceProviderConfigs() {
        return scimServiceFactory.getConfigService()
                                 .getServiceProviderConfiguration();
    }
    
    // **********************************************************
    // Bulk /Bulk POST Bulk modify Resources
    // **********************************************************
    
    @RequestMapping(value = "/Bulk", method = RequestMethod.POST)
    @ResponseBody
    public Object modifyByBulk() {
        return null;
    }
    
    @ExceptionHandler(ScimException.class)
    public ResponseEntity<ScimError> handleException(ScimException ex,
                                                     HttpServletRequest request,
                                                     HttpServletResponse response) {
        return ScimWebUtils.buildResponseEntity(ex);
    }
}
